<script setup>
import { defineComponent, onMounted, ref, watch } from 'vue';

const props = defineProps({
  value: [String, Number],
  prop: String,
  refName: String,
  prefix: Object,
  append: Object,
  prepend: Object,
  suffix: Object,
  blur: {
    type: Function,
    default: () => {}
  },
  focus: {
    type: Function,
    default: () => {}
  },
  change: {
    type: Function,
    default: () => {}
  },
  input: {
    type: Function,
    default: () => {}
  },
  clear: {
    type: Function,
    default: () => {}
  },
})

const emit = defineEmits(['input', 'getRef'])

const val = ref(props.value)
watch(() => props.value, newVal => {
  val.value = newVal
})
emit('input', val) // 传递给父组件

const inputRef = ref(null)
const name =  props.refName || `${props.prop}Ref`
onMounted(() => {
  emit('getRef', { name, value: inputRef.value })
})

// defineComponent 函数接受一个包含组件选项的对象作为参数，可以包含以下选项：

// name: 组件名称，用于调试和警告。
// components: 一个对象，包含了该组件所依赖的其他组件。
// directives: 一个对象，包含了该组件所依赖的自定义指令。
// props: 一个数组或对象，用于声明组件的属性。
// propsEmitter: 一个对象，包含了为组件生成的响应式 props 的方法。
// emits: 一个数组或对象，用于声明组件的事件。
// setup: 一个函数，用于组合组件的逻辑。
// data: 一个函数，用于声明组件的响应式数据。
// computed: 一个对象，包含了组件的计算属性。
// methods: 一个对象，包含了组件的方法。
// watch: 一个对象，包含了组件的监听器。
// beforeCreate: 一个函数，组件实例被创建之前调用。
// created: 一个函数，组件实例被创建之后调用。
// beforeMount: 一个函数，在组件挂载之前调用。
// mounted: 一个函数，在组件挂载之后调用。
// beforeUpdate: 一个函数，在组件更新之前调用。
// updated: 一个函数，在组件更新之后调用。
// beforeUnmount: 一个函数，在组件卸载之前调用。
// unmounted: 一个函数，在组件卸载之后调用。
// render: 一个函数，用于渲染组件的视图。
// 其中，name、components、directives、setup、data、computed、methods、watch、beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeUnmount、unmounted、render 这些选项与 Vue 2.x 中的组件选项是相同的。

// 而 props、propsEmitter、emits 这三个选项则是 Vue 3.x 新增的组件选项，用于更好地支持 TypeScript 类型检查和 IDE 自动提示。
const slotPrefix = defineComponent(props.prefix)
const slotAppend = defineComponent(props.append)
const slotPrepend = defineComponent(props.prepend)
const slotSuffix = defineComponent(props.suffix)
</script>

<template>
  <el-input 
    ref="inputRef"
    v-model="val"
    v-bind="$attrs"
    @blur="blur"
    @focus="focus"
    @change="change"
    @input="input"
    @clear="clear"
  >
    <template #prefix v-if="prefix">
      <slotPrefix />
    </template>
    <template #suffix v-if="suffix">
      <slotAppend />
    </template>
    <template #prepend v-if="prepend">
      <slotPrepend />
    </template>
    <template #append v-if="append">
      <slotSuffix />
    </template>
  </el-input>
</template>

<style lang="scss" scoped></style>
